package com.threeox.commonlibrary.util.request;

import android.content.Intent;
import android.os.Bundle;
import android.os.Message;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.threeox.commonlibrary.CommonApplcation;
import com.threeox.commonlibrary.R;
import com.threeox.commonlibrary.callback.CommonCallback;
import com.threeox.commonlibrary.config.CommonConfig;
import com.threeox.commonlibrary.entity.engine.request.IntentRequestMsg;
import com.threeox.commonlibrary.entity.engine.request.RequestMsg;
import com.threeox.commonlibrary.entity.engine.request.base.BaseRequestMsg;
import com.threeox.commonlibrary.entity.engine.request.network.NetWorkRequestMsg;
import com.threeox.commonlibrary.entity.engine.request.sharedpre.SharedPreReqMsg;
import com.threeox.commonlibrary.entity.engine.request.sqlite.SqliteRequestMsg;
import com.threeox.commonlibrary.inter.IOverallConfig;
import com.threeox.commonlibrary.inter.OnHttpListener;
import com.threeox.commonlibrary.inter.OnRequestListener;
import com.threeox.commonlibrary.util.CommonConstant;
import com.threeox.httplibrary.OkHttpUtils;
import com.threeox.httplibrary.builder.OkHttpRequestBuilder;
import com.threeox.httplibrary.request.RequestCall;
import com.threeox.utillibrary.util.EmptyUtils;
import com.threeox.utillibrary.util.HandlerUtils;
import com.threeox.utillibrary.util.IntentUtils;
import com.threeox.utillibrary.util.NetworkUtils;

import java.io.Serializable;

/**
 *
 * @ClassName: RequestHelper
 *
 * @Description: Todo(请求操作的工具类)
 *
 * @author 赵屈犇
 *
 * @date 创建时间:2016/12/22 下午9:37
 *
 * @version 1.0
 */
public class RequestHelper implements HandlerUtils.OnHandlerListener {

    // 请求对象为Null
    public static final String NOTREQUESTMESSAGE = "NOTREQUESTMESSAGE";
    // 当前网络没有连接
    public static final String NOTNETWORKCONNECTED = "NOTNETWORKCONNECTED";

    protected Intent mIntent;

    protected CommonConfig mCommonConfig;
    protected OnRequestListener listener;
    protected HandlerUtils mHandlerUtils;
    protected CommonApplcation mApplcation;
    protected IOverallConfig mOverallExtend;

    protected SqlIteRequestHelper mSqlIteRequest;
    protected SharedPreRequestHelper mSharedPreRequest;

    protected final int ERRORCODE = 1;// 错误的回调
    protected final int SUCCESSCODE = 0; // 成功的回调

    protected final String ERRORMSGKEY = "ERRORMSGKEY";// 错误信息的Key
    protected final String ERRORDATAKEY = "ERRORDATAKEY";// 错误数据的Key
    protected final String REQUESTMSGKEY = "REQUESTMSGKEY";// 请求对象的Key
    protected final String SUCCESSDATAKEY = "SUCCESSDATAKEY";// 成功数据的Key
    protected final String REQUESTURLMSGKEY = "REQUESTURLMSGKEY";// 请求对象URL的Key

    protected RequestHelper(){
        this.mCommonConfig = CommonConfig.getInstance();
        this.mApplcation = CommonApplcation.getInstance();
        this.mHandlerUtils = HandlerUtils.getInstance().setOnHandlerListener(this);
        if (mCommonConfig != null) {
            this.mOverallExtend = mCommonConfig.getOverallExtend();
        }
    }

    public static RequestHelper newInstance() {
        return new RequestHelper();
    }

    /**
     * 执行请求
     *
     * @param requestMsg
     */
    public void execRequest(final RequestMsg requestMsg) {
        if (requestMsg == null) {
            return;
        }
        execNetWork(requestMsg.getNetwordRequest());
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    execSqlite(requestMsg.getSqliteRequest());
                    // execRequest(requestMsg.getFileRequest());
                    execIntent(requestMsg.getIntentReqMsg());
                    execSharedPre(requestMsg.getSharedPreRequest());
                    BaseRequestMsg customRequest = requestMsg.getCustomRequest();
                    if (mOverallExtend != null && customRequest != null) {
                        if (mOverallExtend != null) {
                            mOverallExtend.execRequest(RequestHelper.this, customRequest, customRequest.getRequestType());
                        }
                    }
                } catch (Exception e) {
                    sendErrorResult(null, null, e, e.getMessage());
                }
            }
        }).start();
    }

    /**
     * 执行请求
     *
     * @param requestMsg
     */
    public void execRequest(final BaseRequestMsg requestMsg) {
        if (requestMsg == null) {
            /*if (listener != null)
                listener.onError(null, null, 0, NOTREQUESTMESSAGE, "请传入请求对象!");*/
            return;
        }
        // 网络请求操作
        if (requestMsg instanceof NetWorkRequestMsg) {
            execNetWork((NetWorkRequestMsg) requestMsg);
        } else {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        if (requestMsg instanceof SqliteRequestMsg) {
                            execSqlite((SqliteRequestMsg) requestMsg);
                        } else if (requestMsg instanceof IntentRequestMsg) {
                            execIntent((IntentRequestMsg) requestMsg);
                        } else if (requestMsg instanceof SharedPreReqMsg) {
                            execSharedPre((SharedPreReqMsg) requestMsg);
                        }
                        if (mOverallExtend != null) {
                            mOverallExtend.execRequest(RequestHelper.this, requestMsg, requestMsg.getRequestType());
                        }
                    } catch (Exception e) {
                        sendErrorResult(requestMsg, null, e, e.getMessage());
                    }
                }
            }).start();
        }
    }

    /**
     * 执行Intent请求
     *
      * @param requestMsg
     */
    public void execIntent(IntentRequestMsg requestMsg) {
        try {
            if (requestMsg == null) {
                return;
            }
            Object intentValue = requestMsg.getIntentValue();
            if (mIntent != null && EmptyUtils.isEmpty(intentValue)) {
                intentValue = getIntentByKey(mIntent, requestMsg.getIntentKey(), requestMsg.getResultClass());
            }
            sendSuccessResult(requestMsg, requestMsg.getIntentKey(), (Serializable) intentValue);
        } catch (Exception e) {
            sendErrorResult(requestMsg, requestMsg.getIntentKey(), e, e.getMessage());
        }
    }

    /**
     * 执行数据存储
     *
     * @param requestMsg
     */
    public void execSharedPre(SharedPreReqMsg requestMsg) {
        if (requestMsg == null) {
            return;
        }
        if (mSharedPreRequest == null) {
            mSharedPreRequest = SharedPreRequestHelper.newInstance(this);
        }
        mSharedPreRequest.execSharedPre(requestMsg);
    }

    /**
     * 请求SqlIte 本地数据库
     *
     * @param requestMsg
     */
    public void execSqlite(SqliteRequestMsg requestMsg) {
        if (requestMsg == null) {
            return;
        }
        if (mSqlIteRequest == null) {
            mSqlIteRequest = SqlIteRequestHelper.newInstance(this);
        }
        mSqlIteRequest.execSqlite(requestMsg);
    }

    /**
     * 请求服务
     *
     * @param requestMsg
     */
    public void execNetWork(final NetWorkRequestMsg requestMsg) {
        if (requestMsg == null) {
            return;
        }
        String url = requestMsg.getServeUrl();
        if (EmptyUtils.isNotEmpty(requestMsg.getRootUrl())){
            url = requestMsg.getRootUrl() + requestMsg.getServeUrl();
        }
        // 检测网络是否连接
        if (!NetworkUtils.isConnected(mApplcation)) {
            onError(requestMsg, url, 0, NOTNETWORKCONNECTED, mApplcation.getString(R.string.net_work_erro), null);
            return;
        }
        if (requestMsg == null) {
            onError(requestMsg, url, 0, NOTREQUESTMESSAGE, "请传入请求对象!", null);
            return;
        }
        OkHttpRequestBuilder builder = null;
        String methodType = requestMsg.getMethodType();
        if (CommonConstant.MethodType.GET.equals(methodType) || EmptyUtils.isEmpty(methodType)) {
            builder = OkHttpUtils.get();
        } else if (CommonConstant.MethodType.POST.equals(methodType)) {
            builder = OkHttpUtils.post();
        } else if (CommonConstant.MethodType.POSTTEXT.equals(methodType)) {
            builder = OkHttpUtils.postString();
        } else if (CommonConstant.MethodType.PUT.equals(methodType)) {
            builder = OkHttpUtils.put();
        } else if (CommonConstant.MethodType.HEAD.equals(methodType)) {
            builder = OkHttpUtils.head();
        } else if (CommonConstant.MethodType.DELETE.equals(methodType)) {
            builder = OkHttpUtils.delete();
        } else if (CommonConstant.MethodType.PATCH.equals(methodType)) {
            builder = OkHttpUtils.patch();
        } else if (CommonConstant.MethodType.POSTFILE.equals(methodType)) {
            builder = OkHttpUtils.postFile();
        }
        if (EmptyUtils.isNotEmpty(builder)) {
            CommonCallback commonCallback = new CommonCallback<>().setMsgKey(requestMsg.getMsgKey()).setReplaceParam(requestMsg.getReplaceParam())
                    .setRespConfigMsg(requestMsg.getRespConfigMsg()).setResultClass(requestMsg.getResultClass());
            builder.url(url).params(requestMsg.getRequestParam()).headers(requestMsg.getHeaders());
            if (mOverallExtend != null) {
                mOverallExtend.onBeforeRequest(requestMsg, builder);
            }
            RequestCall requestCall = builder.build().readTimeOut(requestMsg.getReadTimeOut())
                    .writeTimeOut(requestMsg.getWriteTimeOut()).connTimeOut(requestMsg.getConnTimeOut());
            requestCall.execute(commonCallback.setOnHttpListener(new OnHttpListener() {
                @Override
                public void onSuccess(String url, int id, String msg, Object data) {
                    RequestHelper.this.onSuccess(requestMsg, url, id, msg, data);
                }

                @Override
                public void onError(String url, int id, Object code, String msg, Object data) {
                    RequestHelper.this.onError(requestMsg, url, id, code, msg, data);
                }

                @Override
                public void inProgress(float progress, long total, int id, String url) {
                    RequestHelper.this.inProgress(requestMsg, progress, total, id, url);
                }
            }));
        }
    }

    public void setIntent(Intent intent) {
        this.mIntent = intent;
    }

    public RequestHelper setOnRequestListener(OnRequestListener listener) {
        this.listener = listener;
        return this;
    }

    /**
     * 通过Key值取得对象
     *
     * @param intent
     * @param key
     * @return
     */
    public static Object getIntentByKey(Intent intent, String key) {
        return getIntentByKey(intent, key, JSONObject.class);
    }

    /**
     *
     * @param intent
     * @param key
     * @param clazz
     * @return
     */
    public static Object getIntentByKey(Intent intent, String key, Class clazz) {
        Object result = IntentUtils.get(intent, key);
        if (null == result)
            return result;
        if (result instanceof String) {
            try {
                return JSON.parseObject((String) result, clazz);
            } catch (Exception e) {
                try {
                    return JSON.parseArray((String) result, clazz);
                } catch (Exception e1) {
                    return result;
                }
            }
        }
        return result;
    }

    /**
     * 发送错误结果回调
     *
     * @param errorData
     * @param errorMessage
     */
    public void sendErrorResult(Serializable errorData, String errorMessage) {
        sendErrorResult(null, null, errorData, errorMessage);
    }

    /**
     * 发送错误结果回调
     *
     * @param requestMsg
     * @param url
     * @param errorData
     * @param errorMessage
     */
    public void sendErrorResult(BaseRequestMsg requestMsg, String url, Serializable errorData, String errorMessage) {
        Bundle bundle = new Bundle();
        bundle.putSerializable(ERRORDATAKEY , errorData);
        bundle.putSerializable(ERRORMSGKEY, errorMessage);
        bundle.putSerializable(REQUESTMSGKEY , requestMsg);
        bundle.putString(REQUESTURLMSGKEY, url);
        mHandlerUtils.putWhat(ERRORCODE).put(bundle).send();
    }

    /**
     * 发送成功数据回调
     *
     * @param result
     */
    @Deprecated
    private void sendSuccessResult(Serializable result) {
        sendSuccessResult(null, null, result);
    }


    /**
     * 发送成功数据回调
     *
     * @param requestMsg
     * @param url
     * @param result
     */
    public void sendSuccessResult(BaseRequestMsg requestMsg, String url, Serializable result) {
        if (mOverallExtend != null) {
            try {
                Object data = mOverallExtend.onAfterResponse(url, 0, null, result, result);
                if (data != null) {
                    result = (Serializable) data;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        Bundle bundle = new Bundle();
        bundle.putSerializable(REQUESTMSGKEY , requestMsg);
        bundle.putSerializable(SUCCESSDATAKEY, result);
        bundle.putString(REQUESTURLMSGKEY, url);
        mHandlerUtils.putWhat(SUCCESSCODE).put(bundle).send();
    }

    @Override
    public void onHandleMessage(Message msg) throws Exception {
        int what = msg.what;
        Bundle bundle = msg.getData();
        if (bundle != null) {
            BaseRequestMsg requestMsg = null;
            if (bundle.getSerializable(REQUESTMSGKEY) != null) {
                requestMsg = (BaseRequestMsg) bundle.getSerializable(REQUESTMSGKEY);
            }
            if (ERRORCODE == what) {
                Object exception = null;
                if (bundle.getSerializable(ERRORDATAKEY) != null) {
                    exception = bundle.getSerializable(ERRORDATAKEY);
                }
                onError(requestMsg, bundle.getString(REQUESTURLMSGKEY), 0, exception, bundle.getString(ERRORMSGKEY), exception);
            } else if (SUCCESSCODE == what) {
                Object result = bundle.getSerializable(SUCCESSDATAKEY);
                onSuccess(requestMsg, bundle.getString(REQUESTURLMSGKEY), 0, "请求数据成功...", result);
            }
        }
    }

    /*================子类可以拦截实例化=================*/
    protected void onSuccess(BaseRequestMsg requestMsg, String url, int id, String msg, Object data) {
        if (listener != null) {
            listener.onSuccess(requestMsg, url, id, msg, data);
        }
        if (mOverallExtend != null) {
            mOverallExtend.onAfterSuccess(url, id, msg, data);
        }
    }

    protected void onError(BaseRequestMsg requestMsg, String url, int id, Object code, String msg, Object data) {
        if (listener != null) {
            listener.onError(requestMsg, url, id, code, msg, data);
        }
        if (mOverallExtend != null) {
            mOverallExtend.onAfterError(url, id, code, msg);
        }
    }

    protected void inProgress(BaseRequestMsg requestMsg, float progress, long total, int id, String url) {
        if (listener != null) {
            listener.inProgress(requestMsg, progress, total, id, url);
        }
    }
    /*================子类可以拦截实例化=================*/

}
